package com.flute.icrawler.app.service;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.CanReadFileFilter;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.HttpParams;
import org.apache.log4j.FileAppender;
import org.apache.log4j.PatternLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xbill.DNS.ARecord;
import org.xbill.DNS.DClass;
import org.xbill.DNS.Lookup;
import org.xbill.DNS.Record;
import org.xbill.DNS.TextParseException;
import org.xbill.DNS.Type;

import sun.management.ManagementFactory;

import com.flute.icrawler.app.entity.CrawlHost;
import com.flute.icrawler.app.result.CrawlResultDealThread;
import com.flute.icrawler.app.result.CrawlResultPool;
import com.flute.icrawler.app.result.IStoreable;
import com.flute.icrawler.app.util.ParameterKey;
import com.flute.icrawler.config.CrawlConfig;
import com.flute.icrawler.config.CrawlConfigUtil;
import com.sun.management.OperatingSystemMXBean;

/**
 * 爬虫基础服务类
 * 
 * @author jiangbo
 * 
 */
public class CrawlService {

	private HashMap<String, CrawlHost[]> hmDNStoCHost = new HashMap<String, CrawlHost[]>();

	private static CrawlService crawlService = null;

	private String strMACAddress = "";

	private long startDateTimeMillis = 0L;

	private static final int CPUTIME = 30000;

	private static final int FAULTLENGTH = 10;

	private CrawlResultPool crawlResultPool = new CrawlResultPool();

	private static String localIp = "";

	private int resultDealThreadCount = 0;

	// private SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
	// "yyyy-MM-dd'T'HH:mm:ss");
	// 获取配置
	private CrawlConfig config = CrawlConfigUtil.getBaseConfig();

	private HttpClient threadSafeHttpClient = null;

	private Map<String, org.apache.log4j.Logger> hostToResultLogger = new HashMap<String, org.apache.log4j.Logger>();

	private List<CrawlResultDealThread> crawlResultDealThreadList = new ArrayList<CrawlResultDealThread>();

	private Map<String, Iterator<File>> fileDirToFilesIterator = new HashMap<String, Iterator<File>>();

	private static final String HTTP_SCHEME = "http";
	private static final String HTTPS_SCHEME = "https";

	private static final Logger LOGGER = LoggerFactory
			.getLogger(CrawlService.class);

	private CrawlService() {
		startDateTimeMillis = System.currentTimeMillis();
		resultDealThreadCount = config.getUrl().getResultDealThreadCount();

	}

	public void closeService() {

		LOGGER.info("Begin to close CrawlService");
		closeDefaultStorageService();
		LOGGER.info("Success to close CrawlService!");
	}

	private void initHttpClient(HttpParams params) {

		SchemeRegistry schemeRegistry = new SchemeRegistry();
		schemeRegistry.register(new Scheme(HTTP_SCHEME, PlainSocketFactory
				.getSocketFactory(), 80));
		schemeRegistry.register(new Scheme(HTTPS_SCHEME, SSLSocketFactory
				.getSocketFactory(), 443));

		ClientConnectionManager cm = new ThreadSafeClientConnManager(params,
				schemeRegistry);

		threadSafeHttpClient = new DefaultHttpClient(cm, params);

	}

	/**
	 * 单实例对象
	 * 
	 * @return
	 */
	public static CrawlService getInstance() {
		if (null == crawlService) {
			crawlService = new CrawlService();
		}
		return crawlService;
	}

	/**
	 * 记录失败的链接
	 * 
	 * @param strResult
	 */
	public void logFailResult(String strResult) {

		logResult("failedUrl", strResult);
	}

	/**
	 * 记录每个网站自己的结果文件和链接的对应关系
	 * 
	 * @param hostName
	 *            网站域名
	 * @param strResult
	 *            存储的结果
	 */
	public synchronized void logResult(String hostName, String strResult) {

		// 如果没有该网站自己的结果文件和链接的对应关系
		org.apache.log4j.Logger logger = hostToResultLogger.get(hostName);
		if (null == logger) {
			logger = newResultLogger(hostName);
			if (null == logger) {
				LOGGER.error("ResultLogger init failed! " + hostName);
				return;
			}
			hostToResultLogger.put(hostName, logger);
		}

		logger.info(strResult);

	}

	private org.apache.log4j.Logger newResultLogger(String hostName) {
		// TODO Auto-generated method stub
		org.apache.log4j.Logger logger = org.apache.log4j.Logger
				.getLogger("console");
		String resultDetilPath = "resultLog/" + hostName + "/"
				+ "result.log";

		try {
			logger.addAppender(new FileAppender(new PatternLayout(
					ParameterKey.LOGGER_PATTERN_LAYOUT), resultDetilPath,
					false, false, ParameterKey.LOGGER_MAXSIZE));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			LOGGER.error("CrawlService:", e);
			return null;
		}
		return logger;
	}

	/**
	 * 启动存储服务 存储数据到Cassandra数据库中
	 * 
	 * @param isDaemon
	 *            是否是守护线程
	 */
	public void startDefaultStorageService(boolean isDaemon,
			IStoreable storeable) {

		LOGGER.info("Start DefaultStorageService");

		LOGGER.info("CrawlResultDealThread count is" + resultDealThreadCount);

		for (int i = 0; i < resultDealThreadCount; i++) {
			CrawlResultDealThread crawlResultDealThread = new CrawlResultDealThread(
					storeable);

			crawlResultDealThreadList.add(crawlResultDealThread);
			crawlResultDealThread.setDaemon(isDaemon);
			crawlResultDealThread.start();
		}

		LOGGER.info("CrawlResultDealThread start ok!");
	}

	public void closeDefaultStorageService() {
		LOGGER.info("Begin to close DefaultStorageService");

		int size = crawlResultDealThreadList.size();

		for (int i = 0; i < size; i++) {
			CrawlResultDealThread crawlResultDealThread = crawlResultDealThreadList
					.get(i);
			crawlResultDealThread.setFinished(true);
		}

		LOGGER.info("Success to close DefaultStorageService");

	}

	/**
	 * 对该主机名进行内部DNS注册 更新DNS MAP hmDNStoCHost
	 * 
	 * @param dnsName
	 */
	public boolean registerDNS(String dnsName) {
		Record[] rrecordSet = null; // Retrieved dns records
		// 查找其DN地
		try {
			rrecordSet = (new Lookup(dnsName, Type.A, DClass.IN)).run();
		} catch (TextParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// Get TTL and IP info from the first A record (there may be
		// multiple, e.g. www.washington.edu) then update the CrawlServer
		List<ARecord> arecords = new ArrayList<ARecord>();

		for (int i = 0; i < rrecordSet.length; i++) {

			if (rrecordSet[i].getType() != Type.A) {

				continue;
			}
			arecords.add((ARecord) rrecordSet[i]);
		}

		int size = arecords.size();
		if (arecords.size() == 0) {
			return false;
		}

		CrawlHost[] crawlHosts = new CrawlHost[size];

		for (int i = 0; i < size; i++) {
			ARecord arecord = arecords.get(i);
			crawlHosts[i] = new CrawlHost(arecord.getAddress(), arecord
					.getTTL());

		}

		hmDNStoCHost.put(dnsName, crawlHosts);
		return true;

	}

	// /**
	// * 获取镜像文件保存的路径
	// *
	// * @param url
	// * 链接的url
	// * @return
	// */
	// public String getMirrorFilePath(String url) {
	// DataRecord dataRecord = null;
	// while ((dataRecord = (DataRecord) berkeleyDatabase.peek()) != null) {
	//
	// if (dataRecord.getFieldValue(ParameterKey.URL)
	// .equalsIgnoreCase(url)) {
	// return dataRecord.getFieldValue(ParameterKey.PATH);
	// }
	// }
	// return "";
	// }

	/**
	 * 获取该URL的镜像文件内容 文件过大可能引起内存不足异常
	 * 
	 * @param url
	 * @param charSet
	 * @return
	 */
	// public String getMirrorFileContent(String url, String charSet) {
	// String filePath = getMirrorFilePath(url);
	//
	// if (null == filePath || "".equals(filePath)) {
	//
	// System.out.println("no MirrorFile");
	// return "";
	// }
	// File file = new File(filePath);
	// try {
	// if (!file.exists()) {
	//
	// return "";
	// }
	//
	// BufferedInputStream bufferedInputStream = new BufferedInputStream(
	// new FileInputStream(file));
	// ByteArrayOutputStream os = new ByteArrayOutputStream();
	//
	// byte[] cs = new byte[4096];
	// int readLength = 0;
	// while ((readLength = bufferedInputStream.read(cs)) != -1) {
	//
	// os.write(cs, 0, readLength);
	//
	// }
	//
	// return new String(os.toByteArray(), charSet);
	//
	// } catch (FileNotFoundException e) {
	// // TODO Auto-generated catch block
	// e.printStackTrace();
	// } catch (IOException e) {
	// // TODO Auto-generated catch block
	// e.printStackTrace();
	// }
	//
	// return "";
	// }

	/**
	 * 根据镜像文件的路径获取其链接名
	 * 
	 * @param strMirrorPath
	 * @return
	 */
	// public String getUrl(String strMirrorPath) {
	//
	// DataRecord dataRecord = null;
	// while ((dataRecord = (DataRecord) berkeleyDatabase.peek()) != null) {
	//
	// if (dataRecord.getFieldValue(ParameterKey.PATH).equalsIgnoreCase(
	// strMirrorPath)) {
	// return dataRecord.getFieldValue(ParameterKey.URL);
	// }
	// }
	// return "";
	// }

	/**
	 * 获取主机对应的IP地址 目前只取第一个
	 * 
	 * @param strDNS
	 * @return
	 */
	public String getIP(String strDNS) {

		CrawlHost[] crawlHosts = hmDNStoCHost.get(strDNS);
		if (null == crawlHosts) {
			return "";
		}

		for (int i = 0; i < crawlHosts.length; i++) {
			System.out.println("IP" + strDNS + ":"
					+ crawlHosts[i].getInetAddress().getHostAddress());
		}

		return crawlHosts[0].getInetAddress().getHostAddress();

	}

	/**
	 * 获取MAC地址
	 * 
	 * @return
	 */
	public String getMACAddress() {

		if (null == strMACAddress || "".equals(strMACAddress)) {
			String os = System.getProperty("os.name");
			if (os != null && os.startsWith("Windows")) {
				try {
					String command = "cmd.exe /c ipconfig /all";
					Process p = Runtime.getRuntime().exec(command);
					BufferedReader br = new BufferedReader(
							new InputStreamReader(p.getInputStream(), "GBK"));
					String line;
					while ((line = br.readLine()) != null) {
						if (line.indexOf("物理地址") > 0) {
							int index = line.indexOf(":");
							index += 2;
							strMACAddress = line.substring(index);
							break;
						}
					}
					br.close();
					return strMACAddress.trim();
				} catch (IOException e) {
				}
			}
		}

		return strMACAddress;
	}

	public boolean hasDNSRecord(String dnsName) {

		Iterator<String> iterator = hmDNStoCHost.keySet().iterator();

		while (iterator.hasNext()) {
			String strDNS = (String) iterator.next();

			if (dnsName.contains(strDNS)) {

				return true;
			}

		}
		return false;

	}

	/**
	 * 获取启动的时间
	 * 
	 * @return
	 */
	public long getStartDateTimeMillis() {
		return startDateTimeMillis;
	}

	/**
	 * 获取Linux操作系统CPU占用率
	 * 
	 * @return
	 */
	public static double getCpuRateForLinux() {

		BufferedReader in = null;
		try {
			File file = new File("/proc/stat");
			in = new BufferedReader(new InputStreamReader(new FileInputStream(
					file)));
			StringTokenizer token = new StringTokenizer(in.readLine());
			token.nextToken();
			int user1 = Integer.parseInt(token.nextToken());
			int nice1 = Integer.parseInt(token.nextToken());
			int sys1 = Integer.parseInt(token.nextToken());
			int idle1 = Integer.parseInt(token.nextToken());
			int iowait1 = Integer.parseInt(token.nextToken());
			int irq1 = Integer.parseInt(token.nextToken());
			int softirq1 = Integer.parseInt(token.nextToken());

			Thread.sleep(1000);

			in = new BufferedReader(new InputStreamReader(new FileInputStream(
					file)));
			token = new StringTokenizer(in.readLine());
			token.nextToken();
			int user2 = Integer.parseInt(token.nextToken());
			int nice2 = Integer.parseInt(token.nextToken());
			int sys2 = Integer.parseInt(token.nextToken());
			int idle2 = Integer.parseInt(token.nextToken());
			int iowait2 = Integer.parseInt(token.nextToken());
			int irq2 = Integer.parseInt(token.nextToken());
			int softirq2 = Integer.parseInt(token.nextToken());

			return (float) ((user2 + sys2 + nice2) - (user1 + sys1 + nice1))
					/ (float) ((user2 + nice2 + sys2 + idle2 + iowait2 + irq2 + softirq2) - (user1
							+ nice1 + sys1 + idle1 + iowait1 + irq1 + softirq1));
		} catch (NumberFormatException e) {
			// TODO Auto-generated catch block
			LOGGER.error("CrawlService:", e);

		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			LOGGER.error("CrawlService:", e);

		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			LOGGER.error("CrawlService:", e);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			LOGGER.error("CrawlService:", e);
		} finally {
			try {
				in.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				LOGGER.error("CrawlService:", e);
			}
		}
		return 0;

	}

	/**
	 * 获取本机的IP地址
	 * 
	 * @return
	 */
	public static String getLocalIp() {

		try {
			if (null == localIp || "".equalsIgnoreCase(localIp)) {
				localIp = InetAddress.getLocalHost().getHostAddress();
			}

		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			LOGGER.error("localIp will be set default", e);
			return ParameterKey.IP_DEFAULT;
		} catch (Exception e) {
			LOGGER.error("", e);
			return ParameterKey.IP_DEFAULT;
		}
		return localIp;
	}

	/**
	 * 获得windows CPU使用率.
	 * 
	 * @return 返回cpu使用率
	 * @author GuoHuang
	 */
	public static double getCpuRateForWindows() {
		try {
			String procCmd = System.getenv("windir")
					+ "\\system32\\wbem\\wmic.exe process get Caption,CommandLine,"
					+ "KernelModeTime,ReadOperationCount,ThreadCount,UserModeTime,WriteOperationCount";
			// 取进程信息

			long[] c0 = readCpu(Runtime.getRuntime().exec(procCmd));
			Thread.sleep(CPUTIME);
			long[] c1 = readCpu(Runtime.getRuntime().exec(procCmd));
			if (c0 != null && c1 != null) {
				long idletime = c1[0] - c0[0];
				long busytime = c1[1] - c0[1];
				return 1.0 * (busytime) / (busytime + idletime);
			} else {
				return 0.0;
			}
		} catch (NumberFormatException e) {
			LOGGER.error("getCpuRateForWindows:NumberFormatException");
			return 0.0;
		} catch (Exception ex) {
			ex.printStackTrace();
			return 0.0;
		}
	}

	/**
	 * 
	 * 读取CPU信息.
	 * 
	 * @param proc
	 * @return
	 * @author GuoHuang
	 */
	private static long[] readCpu(final Process proc)
			throws NumberFormatException {
		long[] retn = new long[2];
		try {
			proc.getOutputStream().close();
			InputStreamReader ir = new InputStreamReader(proc.getInputStream());
			LineNumberReader input = new LineNumberReader(ir);
			String line = input.readLine();
			if (line == null || line.length() < FAULTLENGTH) {
				return null;
			}
			int capidx = line.indexOf("Caption");
			int cmdidx = line.indexOf("CommandLine");
			int rocidx = line.indexOf("ReadOperationCount");
			int umtidx = line.indexOf("UserModeTime");
			int kmtidx = line.indexOf("KernelModeTime");
			int wocidx = line.indexOf("WriteOperationCount");
			long idletime = 0;
			long kneltime = 0;
			long usertime = 0;
			while ((line = input.readLine()) != null) {
				if (line.length() < wocidx) {
					continue;
				}
				// 字段出现顺序：Caption,CommandLine,KernelModeTime,ReadOperationCount,
				// ThreadCount,UserModeTime,WriteOperation
				String caption = substring(line, capidx, cmdidx - 1).trim();
				String cmd = substring(line, cmdidx, kmtidx - 1).trim();
				if (cmd.indexOf("wmic.exe") >= 0) {
					continue;
				}
				// log.info("line="+line);
				if (caption.equals("System Idle Process")
						|| caption.equals("System")) {
					idletime += Long.valueOf(
							substring(line, kmtidx, rocidx - 1).trim())
							.longValue();
					idletime += Long.valueOf(
							substring(line, umtidx, wocidx - 1).trim())
							.longValue();
					continue;
				}

				kneltime += Long.valueOf(
						substring(line, kmtidx, rocidx - 1).trim()).longValue();
				usertime += Long.valueOf(
						substring(line, umtidx, wocidx - 1).trim()).longValue();
			}
			retn[0] = idletime;
			retn[1] = kneltime + usertime;
			return retn;
		} catch (IOException ex) {
			ex.printStackTrace();
		} finally {
			try {
				proc.getInputStream().close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	/**
	 * 由于String.subString对汉字处理存在问题（把一个汉字视为一个字节)，因此在 包含汉字的字符串时存在隐患，现调整如下：
	 * 
	 * @param src
	 *            要截取的字符串
	 * @param start_idx
	 *            开始坐标（包括该坐标)
	 * @param end_idx
	 *            截止坐标（包括该坐标）
	 * @return
	 */
	private static String substring(String src, int start_idx, int end_idx) {
		byte[] b = src.getBytes();
		String tgt = "";
		for (int i = start_idx; i <= end_idx; i++) {
			tgt += (char) b[i];
		}
		return tgt;
	}

	/**
	 * 获取操作系统名称
	 * 
	 * @return
	 */
	public static String getOSName() {

		String osName = System.getProperty("os.name");
		LOGGER.info("OS Name:" + osName);
		return osName;
	}

	/**
	 * 获取CPU占用率
	 * 
	 * @return
	 */
	public static double getOSCpuRate() {
		String osName = getOSName();

		osName = osName.toLowerCase();
		if (osName.contains("windows")) {
			return getCpuRateForWindows();
		} else if (osName.contains("linux")) {

			return getCpuRateForLinux();
		} else {
			LOGGER.error("unknow OS!" + osName);
		}
		return 0;
	}

	/**
	 * 获取操作系统内存占用率
	 * 
	 * @return
	 */
	public static double getOSMemoryRate() {
		OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory
				.getOperatingSystemMXBean();
		// 总的物理内存
		long totalMemorySize = osmxb.getTotalPhysicalMemorySize();
		// 剩余的物理内存
		long freePhysicalMemorySize = osmxb.getFreePhysicalMemorySize();

		return 1 - 1.0 * freePhysicalMemorySize / totalMemorySize;
	}

	/**
	 * 获取JVM内存占用率
	 * 
	 * @return
	 */
	public static double getJVMMemoryRate() {
		// 可使用内存
		long totalMemory = Runtime.getRuntime().totalMemory();
		// 剩余内存
		long freeMemory = Runtime.getRuntime().freeMemory();

		long maxMemory = Runtime.getRuntime().maxMemory();

		LOGGER.info("totalMemory=" + totalMemory + "freeMemory=" + freeMemory
				+ "maxMemory=" + maxMemory);

		return 1.0 * (totalMemory - freeMemory) / totalMemory;
	}

	public CrawlResultPool getCrawlResultPool() {
		return crawlResultPool;
	}

	// private long getMaxFetchRate() {
	// // TODO Auto-generated method stub
	// return 0;
	// }

	/**
	 * 获取线程安全的HTTPCLIENT实例
	 * 
	 * @return
	 */
	public synchronized HttpClient getThreadSafeHttpClient(HttpParams params) {

		if (null == threadSafeHttpClient) {
			initHttpClient(params);
			return threadSafeHttpClient;
		}
		return threadSafeHttpClient;
	}

	/**
	 * 获取该文件夹中的文件
	 * 
	 * @param fileDir
	 *            文件夹名称
	 * @param count
	 *            获取的个数
	 * @return
	 */
	public synchronized File[] getFilesIterator(String fileDir, int count) {
		Iterator<File> iterator = getFilesIterator(fileDir);

		int j = 0;
		HashSet<File> hashSet = new HashSet<File>();
		while (iterator.hasNext() && j < count) {

			hashSet.add(iterator.next());

			j++;
		}

		return hashSet.toArray(new File[0]);

	}

	/**
	 * 获取该文件夹的列表
	 * 
	 * @param fileDir
	 * @return
	 */
	public Iterator<File> getFilesIterator(String fileDir) {
		if (fileDirToFilesIterator.containsKey(fileDir)) {
			return fileDirToFilesIterator.get(fileDir);
		} else {
			Iterator<File> iterator = FileUtils.iterateFiles(new File(fileDir),
					CanReadFileFilter.CAN_READ, null);
			fileDirToFilesIterator.put(fileDir, iterator);
			return iterator;
		}
	}

	/**
	 * 获取文件夹的列表
	 * 
	 * @param fileDir
	 * @return
	 */
	public Iterator<File> getFilesIterator(File fileDir) {
		if (fileDirToFilesIterator.containsKey(fileDir)) {
			return fileDirToFilesIterator.get(fileDir.getAbsolutePath());
		} else {
			Iterator<File> iterator = FileUtils.iterateFiles(fileDir,
					CanReadFileFilter.CAN_READ, null);
			fileDirToFilesIterator.put(fileDir.getAbsolutePath(), iterator);
			return iterator;
		}
	}

	/**
	 * 检查是否满足正则过滤以及选择的条件
	 * 
	 * @param text
	 * @param filterReg
	 * @param matchReg
	 * @return
	 */
	public static boolean match(String text, String filterReg, String matchReg) {
		boolean matchRegCheck = false;
		boolean filterRegCheck = false;
		if ("".equalsIgnoreCase(matchReg) || null == matchReg) {
			matchRegCheck = true;
		} else {
			Pattern acceptPattern = Pattern.compile(matchReg);
			Matcher match = acceptPattern.matcher(text);
			if (match.find()) {
				matchRegCheck = true;
			}
		}

		if ("".equalsIgnoreCase(filterReg) || null == filterReg) {
			filterRegCheck = true;
		} else {
			Pattern acceptPattern = Pattern.compile(filterReg);
			Matcher match = acceptPattern.matcher(text);
			// 没找到说明没有被过滤检查通过
			if (!match.find()) {
				filterRegCheck = true;
			}
		}

		if (filterRegCheck && matchRegCheck) {
			return true;
		} else {
			return false;
		}

	}

	/**
	 * 创建文件及其包含的文件夹
	 * 
	 * @param strFile
	 * @throws IOException
	 */
	public static void createFile(String strFile) throws IOException {
		File file = new File(strFile);

		File fileDirs = new File(file.getParent());
		if (!fileDirs.exists()) {
			fileDirs.mkdirs();
		}

		// 文件不存在则创建
		if (!file.exists()) {

			file.createNewFile();
		}

	}

	public static boolean isUrl(String url) {
		Pattern p = Pattern.compile("(http|www|ftp)://.*",
				Pattern.CASE_INSENSITIVE);
		Matcher m = p.matcher(url);

		return m.find();
	}

	public int getResultDealThreadCount() {
		return resultDealThreadCount;
	}

	public static void main(String[] args) {

		// String strCookie = "Windows Vista";

		System.out.println(CrawlService.isUrl("ftp://dfd"));

		String str = CrawlService.getOSName();

		// System.out.println(CrawlService.getInstance().getMirrorFilePath(
		// "http://auto.163.com/10/0915/19/6GL82VOH00081GDM.html"));
		str = str.toLowerCase();
		System.out.println(str + str.contains("windows"));

		System.out.println("OSCpuRate:" + CrawlService.getOSCpuRate());
		System.out.println("OSMemoryRate:" + CrawlService.getOSMemoryRate());

		System.out.println("JVMMemoryRate:" + CrawlService.getJVMMemoryRate());

	}
}
